﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Xml.Serialization;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WorkflowActions;
using Microsoft.Office.Workflow.Utility;
using System.Diagnostics;
using System.Collections.Generic;
using System.Web.UI;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using CaveDigital.BoardMeeting2007Lite.ServerLib;
using CaveDigital.BoardMeeting2007Lite.Minutes;
using System.Globalization;
using System.Web;
using Microsoft.SharePoint.Workflow;
using System.Text;
using CaveDigital.SharedLib;

namespace VoteWorkFlow
{
    public sealed partial class Workflow1: SequentialWorkflowActivity
    {
        private const string EVENT_PRODUCTNAME = "VoteWorkFlow";

		#region Fields (23) 


        public List<string> child = new List<string>();

        string taskResult = string.Empty;
        internal string secretaryName;
        public string mayorVoteResult = string.Empty;
        public String historyDescription = default(System.String);
        public String historyOutcome = default(System.String);

        internal bool mayorsDecided = false;
        bool taskStatusBool; //WARNING EXPLANATION. The value of this field is used only in workflow designer mode;
        internal int votesInFavor = 0;
        internal int votesAgainst = 0;
        internal int votesAbstain = 0;
        internal int countVotesAtTime = 0;
        internal int currentUser = 0;

        public ExecutionType replictorExecutionType = default(System.Workflow.Activities.ExecutionType);
        public Guid workflowId = default(System.Guid);
        public Guid createTask_TaskId1 = default(System.Guid);
        public Guid taskID;
        public Guid createTask1_TaskId1 = default(System.Guid);
        public IList replicatorInitialChildData = default(System.Collections.IList);
        public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties();
        public Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties createTask1_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties onTaskChanged1_AfterProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties onTaskChanged1_BeforeProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

		#endregion Fields 

		#region Constructors (1) 

        public Workflow1()
        {
            InitializeComponent();
        }

		#endregion Constructors 

		#region Event Handlers (5) 

        private void completeTask1_MethodInvoking(object sender, EventArgs e)
        {
            if (child.Count == countVotesAtTime)
            {
                ShowFinalResult();
                workflowProperties.Item.ModerationInformation.Status = 0;
                workflowProperties.Item.Update();
            }
        }

        private void createTask1_MethodInvoking(object sender, EventArgs e)
        {
            int lcid = workflowProperties.Item.Web.ParentWeb.CurrencyLocaleID;
            CultureInfo specificCulture = new CultureInfo(lcid);
            SPUser user = workflowProperties.Web.ParentWeb.CurrentUser;
            secretaryName = user.Name;
            workflowProperties.Item[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(MinutesConstants.RESOURCES_CAPTION_MEETING_AGENDA_RESULT_KEY, specificCulture)] = GlobalConstants.MEETINGSITE_DOCLIB_IMAGES_ON_VOTING;
            StartAssigningTasks();
            workflowProperties.Item.Update();
            if (child.Count == currentUser)
            {
                workflowProperties.Item.ModerationInformation.Status = 0;
                workflowProperties.Item.Update();
            }
        }

        private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
        {
            VerifyIfTaskChanged();
        }

        private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
        {
            if (UserIsRoleSecretary())
            {
                bool ifWorkFlowWasVoted = Convert.ToBoolean(workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_ISVOTED]);
                string approvedStatus = workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_APROVALSTATUS].ToString();
                if (!ifWorkFlowWasVoted && approvedStatus == WorkflowConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_APROVALSTATUS_VALUE0)
                    GetUsersToAssign(workflowProperties.Item.Web.ParentWeb.CurrencyLocaleID);
            }
        }

        private void replicatorActivity1_Initialized(object sender, EventArgs e)
        {
            replicatorActivity1.InitialChildData = this.child;
            replicatorActivity1.ExecutionType = ExecutionType.Parallel;         
        }

		#endregion Event Handlers 

        #region Private Functions
        private void ShowFinalResult()
        {
            int lcid = workflowProperties.Item.Web.ParentWeb.CurrencyLocaleID;
            CultureInfo specificCulture = new CultureInfo(lcid);
            if (votesInFavor > votesAgainst)
            {
                workflowProperties.Item[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(MinutesConstants.RESOURCES_CAPTION_MEETING_AGENDA_RESULT_KEY, specificCulture)] = GlobalConstants.MEETINGSITE_DOCLIB_IMAGES_ON_APPROVED;
                workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_PROPOSALRESULT] = 
                    CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetWorkflowCaptionString(WorkflowConstants.RESOURCES_CAPTION_APPROVED_KEY, specificCulture);
                SetVotesInDocLib();
            }
            if (votesInFavor < votesAgainst)
            {
                workflowProperties.Item[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(MinutesConstants.RESOURCES_CAPTION_MEETING_AGENDA_RESULT_KEY, specificCulture)] = GlobalConstants.MEETINGSITE_DOCLIB_IMAGES_REJECTED;
                workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_PROPOSALRESULT] =
                    CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetWorkflowCaptionString(WorkflowConstants.RESOURCES_CAPTION_REJECTED_KEY, specificCulture);
                workflowProperties.Item.Update();
                SetVotesInDocLib();
            }
            if (votesInFavor == votesAgainst)
                if (mayorVoteResult == WorkflowConstants.PROPOSAL_VOTE_RESULT_APPROVED)
                {
                    workflowProperties.Item[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(MinutesConstants.RESOURCES_CAPTION_MEETING_AGENDA_RESULT_KEY, specificCulture)] = GlobalConstants.MEETINGSITE_DOCLIB_IMAGES_ON_APPROVED;
                    workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_PROPOSALRESULT] =
                        CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetWorkflowCaptionString(WorkflowConstants.RESOURCES_CAPTION_APPROVED_KEY, specificCulture);
                    workflowProperties.Item.Update();
                    SetVotesInDocLib();
                    workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_MAYORDECIDED] = true;
                }
                else
                {
                    workflowProperties.Item[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(MinutesConstants.RESOURCES_CAPTION_MEETING_AGENDA_RESULT_KEY, specificCulture)] = GlobalConstants.MEETINGSITE_DOCLIB_IMAGES_REJECTED;
                    workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_PROPOSALRESULT] =
                        CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetWorkflowCaptionString(WorkflowConstants.RESOURCES_CAPTION_REJECTED_KEY, specificCulture);
                    workflowProperties.Item.Update();
                    SetVotesInDocLib();
                    workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_MAYORDECIDED] = true;
                }
            workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_ISVOTED] = true;
            workflowProperties.Item.Update();
        }

        private void SetVotesInDocLib()
        {
           workflowProperties.Item[ GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_VOTESINFAVOR] = votesInFavor;
           workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_VOTESAGAINST] = votesAgainst;
           workflowProperties.Item[GlobalConstants.MEETINGSITE_DOCLIB_MEETINGAGENDA_COL_VOTESABSTAIN] = votesAbstain;
           workflowProperties.Item.Update();
        }

        private void StartAssigningTasks()
        {
            try
            {
                int lcid = workflowProperties.Item.Web.ParentWeb.CurrencyLocaleID;
                CultureInfo specificCulture = new CultureInfo(lcid);
                SPWeb currentWeb = workflowProperties.Item.Web.ParentWeb;
                SPGroup grupo = currentWeb.SiteGroups[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetRoleString(Roles.Mayors, specificCulture)];
                SPUser user = currentWeb.EnsureUser(grupo.Users[0].LoginName);
                string mayor = user.LoginName;
                if (child[currentUser] == mayor)
                {
                    CorrelationToken token = new CorrelationToken();
                    token.Name = WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_TASKTOKEN;
                    token.OwnerActivityName = WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_REPLICATORACTIVITY1;
                    createTask_TaskId1 = Guid.NewGuid();
                    this.taskStatusBool = false;
                    createTask1_TaskProperties1.TaskType = 3;
                    createTask1_TaskProperties1.AssignedTo = (string)this.replicatorActivity1.CurrentChildData[currentUser];
                    createTask1_TaskProperties1.Title = string.Concat(
                        CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetWorkflowCaptionString(WorkflowConstants.RESOURCES_CAPTION_PLEASEVOTE_KEY, specificCulture)," ",
                        workflowProperties.Item.Name);
                    currentUser++;
                }
                else
                {
                    CorrelationToken token = new CorrelationToken();
                    token.Name = WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_TASKTOKEN;
                    token.OwnerActivityName = WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_REPLICATORACTIVITY1;
                    createTask_TaskId1 = Guid.NewGuid();
                    this.taskStatusBool = false;
                    createTask1_TaskProperties1.TaskType = 2;
                    createTask1_TaskProperties1.AssignedTo = (string)this.replicatorActivity1.CurrentChildData[currentUser];
                    createTask1_TaskProperties1.Title = string.Concat(
                        CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetWorkflowCaptionString(WorkflowConstants.RESOURCES_CAPTION_PLEASEVOTE_KEY, specificCulture),
                        workflowProperties.Item.Name);
                    currentUser++;
                }
            }
            catch (Exception)
            {
                System.Diagnostics.EventLog.WriteEntry(EVENT_PRODUCTNAME, "The CaveDigital Board Meeting 2007 Lite VoteWorkFlow, was not initiated successfully.", EventLogEntryType.Error);
            }
        }

        private void GetUsersToAssign(int lcid)
        {
            CultureInfo specificCulture = new CultureInfo(lcid);            
            SPList myList = workflowProperties.Web.Lists[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetCollectionObjectsString(Localization.RESOURCES_CAPTION_MEETINGSITE_PARTICIPANTS_KEY, specificCulture)];// MeetingSiteObjects.ParticipantsList.ToString()];//Localization.GetCollectionObjectsStringFLOW( RESOURCES_CAPTION_MEETINGSITE_PARTICIPANTS_KEY,  CultureInfo.GetCultureInfo(workflowProperties.we.ParentWeb.l))];
            string userNameQueryName = CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(WorkflowConstants.PARTICIPANTS_USERNAME_DISPLAY_NAME, specificCulture);
            SPQuery queryParticipant = new SPQuery();
            queryParticipant.Query = WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY1 + Wss30.EscapeSpecialCharacters(userNameQueryName) + WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY2 + CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(WorkflowConstants.PARTICIPANTS_ROLE_DISPLAY_NAME, specificCulture) + WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY3 + CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetRoleString(Roles.Participant, specificCulture) + WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY4;
            SPListItemCollection ItemsDaListaParticipant = myList.GetItems(queryParticipant);
            foreach (SPListItem partc in ItemsDaListaParticipant)
                child.Add(partc[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(WorkflowConstants.PARTICIPANTS_USERNAME_DISPLAY_NAME, specificCulture)].ToString());
            SPQuery queryMayor = new SPQuery();
            queryMayor.Query = WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY1 + Wss30.EscapeSpecialCharacters(userNameQueryName) + WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY2 + CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(WorkflowConstants.PARTICIPANTS_ROLE_DISPLAY_NAME, specificCulture) + WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY3 + CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetRoleString(Roles.Mayor, specificCulture) + WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_QUERY4;
            SPListItemCollection ItemsDaListaMayor = myList.GetItems(queryMayor);
            foreach (SPListItem mayor in ItemsDaListaMayor)
                child.Add(mayor[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetListColumn(WorkflowConstants.PARTICIPANTS_USERNAME_DISPLAY_NAME, specificCulture)].ToString());
        }

        private void VerifyIfTaskChanged()
        {
            int lcid = workflowProperties.Item.Web.ParentWeb.CurrencyLocaleID;
            CultureInfo specificCulture = new CultureInfo(lcid);
            string taskStatus = onTaskChanged1.AfterProperties.ExtendedProperties[WorkflowConstants.INTERNAL_COMMANDS_WORKFLOW_TASKSTATUS].ToString();
            string currentUser = onTaskChanged1.BeforeProperties.AssignedTo;           
            SPWeb currentWeb = workflowProperties.Web.ParentWeb;
            SPGroup grupo = currentWeb.SiteGroups[CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetRoleString(Roles.Mayors, specificCulture)];
            SPUser user = grupo.Users[0];
            string mayor = user.LoginName;
            if (currentUser == mayor)
            {
                switch (taskStatus)
                {
                    case WorkflowConstants.PROPOSAL_VOTE_RESULT_APPROVED:
                        ++votesInFavor;
                        ++countVotesAtTime;
                        workflowProperties.TaskList.Description = onTaskChanged1.AfterProperties.ExtendedProperties[WorkflowConstants.INTERNAL_COMMANDS_INFOPATH_FORMS_COMMENTS].ToString();
                        workflowProperties.TaskList.Update();
                        break;
                    case WorkflowConstants.PROPOSAL_VOTE_RESULT_REJECTED:
                        ++votesAgainst;
                        ++countVotesAtTime;
                        workflowProperties.TaskList.Description = onTaskChanged1.AfterProperties.ExtendedProperties[WorkflowConstants.INTERNAL_COMMANDS_INFOPATH_FORMS_COMMENTS].ToString();
                        workflowProperties.TaskList.Update();
                        break;
                }
                mayorVoteResult = taskStatus;
                taskStatusBool = true;
            }
            else
            {
                switch (taskStatus)
                {
                    case WorkflowConstants.PROPOSAL_VOTE_RESULT_APPROVED:
                        ++votesInFavor;
                        ++countVotesAtTime;
                        workflowProperties.TaskList.Description = onTaskChanged1.AfterProperties.ExtendedProperties[WorkflowConstants.INTERNAL_COMMANDS_INFOPATH_FORMS_COMMENTS].ToString();
                        workflowProperties.TaskList.Update();
                        break;
                    case WorkflowConstants.PROPOSAL_VOTE_RESULT_REJECTED:
                        ++votesAgainst;
                        ++countVotesAtTime;
                        workflowProperties.TaskList.Description = onTaskChanged1.AfterProperties.ExtendedProperties[WorkflowConstants.INTERNAL_COMMANDS_INFOPATH_FORMS_COMMENTS].ToString();
                        workflowProperties.TaskList.Update();
                        break;
                    case WorkflowConstants.PROPOSAL_VOTE_RESULT_ABSTAINED:
                        ++votesAbstain;
                        ++countVotesAtTime;
                        workflowProperties.TaskList.Description = onTaskChanged1.AfterProperties.ExtendedProperties[WorkflowConstants.INTERNAL_COMMANDS_INFOPATH_FORMS_COMMENTS].ToString();
                        workflowProperties.TaskList.Update();
                        break;
                }
                taskStatusBool = true;
            }
        }

        private bool UserIsRoleSecretary()
        {
            int lcid = workflowProperties.Item.Web.ParentWeb.CurrencyLocaleID;
            CultureInfo specificCulture = new CultureInfo(lcid);

            SPGroup secretaryGroup = 
                workflowProperties.Web.ParentWeb.SiteGroups[
                    CaveDigital.BoardMeeting2007Lite.ServerLib.Localization.GetRoleString(Roles.Secretaries, specificCulture)];
            for (int i = 0; i < secretaryGroup.Users.Count; i++)
                if (secretaryGroup.Users[i].ID == workflowProperties.Web.CurrentUser.ID)
                    return true;
            return false;
        }
        
        #endregion
    }
}